using System;
using System.Diagnostics;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using AppliedRecognition.Util;

namespace AppliedRecognition.Speech.TaskSupport
{
	public enum TBSwitchResultStatus
	{
		Success,
		Failed,
		PartialSuccess
	}
	public class TBSwitchResult
	{
		public TBSwitchResultStatus status;
		public string data;
	}

	public class TaskBarSwitch
	{

		private Guid IAccGuid;
		private ARTraceSwitch CommandTS;
		public TaskBarSwitch()
		{
			IAccGuid  = Marshal.GenerateGuidForType(typeof(Accessibility.IAccessible));
			CommandTS = new ARTraceSwitch("Command", "Actions");
		}
		//http://forums.msnfanatic.com/index.php?showtopic=11985

		public void SwitchToSubItem(int taskNum,IntPtr Owner)
		{
			WindowSupport.SendInputDownArrowEnter((uint)taskNum);
		}


		public TBSwitchResult SwitchToItem(int taskNum,IntPtr Owner)
		{
			TBSwitchResult r = new TBSwitchResult();
			r.status = TBSwitchResultStatus.Failed;
			
			int ctr=0;
			int childCount=0;
			int recChildCount=0;
			string name;
			object[] Children;
			try
			{
				Accessibility.IAccessible ia=null;
				AccessibleRole role;

				if( SystemTaskBar == IntPtr.Zero )
				{
					r.data = "Taskbar is null";
					CommandTS.WError(r.data);
					return r;
				}

				MSAA.AccessibleObjectFromWindow(SystemTaskBar,(int)MSAA.NativeMsg.OBJID_CLIENT,ref IAccGuid,ref ia);
				childCount  = ia.accChildCount;
				Children = new object[childCount];
				MSAA.AccessibleChildren(ia,0,childCount,Children,out recChildCount);
				foreach (object id in Children)
				{
					string defAction ="";
					AccessibleStates states = (AccessibleStates)ia.get_accState(id);
					if ((states & AccessibleStates.Invisible)!=0) continue;

					name = ia.get_accName(id);
					role = (System.Windows.Forms.AccessibleRole) ia.get_accRole(id);
					defAction = ia.get_accDefaultAction(id);
					
					if (++ctr == taskNum )
					{
						if (defAction != "Press") // grouped
						{
							ia.accDoDefaultAction(id);
							r.status = TBSwitchResultStatus.PartialSuccess;
							return r;
						}
						else
						{
							uint tbThreadID = PWin32.GetWindowThreadProcessId(SystemTaskBar,0);
							uint QSThreadID = PWin32.GetWindowThreadProcessId(Owner,0);
							bool res = PWin32.AttachThreadInput(QSThreadID,tbThreadID,true);
							ia.accDoDefaultAction(id);
							PWin32.AttachThreadInput(QSThreadID,tbThreadID,false);
							r.data = name;
							r.status = TBSwitchResultStatus.Success;
							return r;
						}
					}
					
				}
			}
			catch (COMException)
			{
			}
			return r;
		}

		private IntPtr _SystemTaskBar;
		internal IntPtr SystemTaskBar
		{
			get 
			{
				if (_SystemTaskBar == IntPtr.Zero)
				{
					IntPtr Shell_TrayWnd = PWin32.FindWindow("Shell_TrayWnd","");
					Debug.Assert(Shell_TrayWnd != IntPtr.Zero);

					IntPtr ReBarWindow32 = PWin32.FindWindowEx(Shell_TrayWnd,IntPtr.Zero,"ReBarWindow32",IntPtr.Zero);
					Debug.Assert(ReBarWindow32 != IntPtr.Zero);
					
					IntPtr MSTaskSwWClass = PWin32.FindWindowEx(ReBarWindow32,IntPtr.Zero,"MSTaskSwWClass",IntPtr.Zero);
					Debug.Assert(MSTaskSwWClass != IntPtr.Zero);
					
					_SystemTaskBar = PWin32.FindWindowEx(MSTaskSwWClass,IntPtr.Zero, "ToolbarWindow32",IntPtr.Zero);
					Debug.Assert(_SystemTaskBar != IntPtr.Zero);
				}
				return _SystemTaskBar;
			}
		}

		private void W32ExMsg(string msg)
		{
			Win32Exception ex = new Win32Exception();
			CommandTS.WError(msg + " (" + ex.NativeErrorCode.ToString() + ") "+ ex.Message);
		}
	}
}
